package com.fc.advbox.service.impl;

import com.fc.advbox.dao.EquipmentDao;
import com.fc.advbox.dao.EquipmentMaintainDao;
import com.fc.advbox.dao.OrgAcctDao;
import com.fc.advbox.dao.OrgAcctTxnDao;
import com.fc.advbox.entity.*;
import com.fc.advbox.service.IEquipmentMaintainService;
import com.fc.advbox.service.IOrgAcctService;
import com.fc.advbox.service.IOrgService;
import com.fc.advbox.utils.Constant;
import com.fc.advbox.utils.DateTimeHelper;
import com.fc.advbox.utils.RRException;
import com.fc.advbox.utils.StringUtils;
import com.google.common.collect.Maps;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * Created by E7450 on 2018/6/21.
 */
@Service("equipmentMaintainService")
public class EquipmentMaintainServiceImpl implements IEquipmentMaintainService {

    @Autowired
    private EquipmentMaintainDao equipmentMaintainDao;

    @Autowired
    private EquipmentDao equipmentDao;

    @Autowired
    private IOrgService orgService;

    @Autowired
    private OrgAcctDao orgAcctDao;

    @Autowired
    private OrgAcctTxnDao orgAcctTxnDao;

    @Override
    public List<EquipmentMaintainEntity> queryList(Map<String, Object> params) {
        return equipmentMaintainDao.queryList(params);
    }

    @Override
    public EquipmentMaintainEntity queryObject(Long id) {
        return equipmentMaintainDao.queryObject(id);
    }

    @Override
    public void save(EquipmentMaintainEntity equipmentMaintainEntity) {
        EquipmentEntity equipmentEntity = equipmentDao.queryByCode(equipmentMaintainEntity.getCode());
        if(equipmentEntity == null)
        {
            throw new RRException("输入的编码未找到设备, 请重新输入");
        }

        equipmentMaintainEntity.setEquipmentId(equipmentEntity.getId());
        equipmentMaintainEntity.setTenantId(equipmentEntity.getTenantId());
        equipmentMaintainEntity.setStatus(Constant.EquipmentMaintainStatus.MAINTAINING.getValue());
        equipmentMaintainEntity.setStartDate(new Date());
        equipmentMaintainEntity.setEquipmentOriginalStatus(equipmentEntity.getStatus());
        equipmentMaintainDao.save(equipmentMaintainEntity);

        Map<String, Object> params = Maps.newHashMap();
        params.put("id", equipmentMaintainEntity.getEquipmentId());
        params.put("status", Constant.EquipmentStatus.MAINTAINING.getValue());
        equipmentDao.updateStatus(params);
    }

    @Override
    public void update(EquipmentMaintainEntity equipmentMaintainEntity) {

        EquipmentMaintainEntity maintainEntityDb = equipmentMaintainDao.queryObject(equipmentMaintainEntity.getId());
        if(maintainEntityDb == null)
        {
            throw new RRException("通过ID未找到维修信息!");
        }

        // 更新维修状态获取设备状态
        String equipmentStatus = null;
        if(Constant.EquipmentMaintainStatus.MAINTAINED.getValue().equals(equipmentMaintainEntity.getStatus()))
        {
            // 维修完成, 则恢复设备原有状态
            equipmentStatus = maintainEntityDb.getEquipmentOriginalStatus();
            equipmentMaintainEntity.setEndDate(new Date()); // 设置完成时间
        }
        else if (Constant.EquipmentMaintainStatus.DISCARD.getValue().equals(equipmentMaintainEntity.getStatus()))
        {
            // 无法维修则，则设置设备的状态为报废
            equipmentStatus = Constant.EquipmentStatus.DISCARD.getValue();
            equipmentMaintainEntity.setEndDate(new Date()); // 设置完成时间

        }
        else if(Constant.EquipmentMaintainStatus.MAINTAINING.getValue().equals(equipmentMaintainEntity.getStatus()))
        {
            equipmentStatus = Constant.EquipmentStatus.MAINTAINING.getValue();
        }

        // 更新维修信息
        equipmentMaintainDao.update(equipmentMaintainEntity);

        // 查询该机器是否还有正在维修的记录，如果有，不更新，如果全部维修完成，则更新设备的状态（更新为设备之前的状态）
        List<EquipmentMaintainEntity> maintainHistoryList
                = equipmentMaintainDao.queryOpeningMaintainHistoryRecordsByEquipmentId(maintainEntityDb.getEquipmentId());
        if(!StringUtils.isEmpty(equipmentStatus)
                && (maintainHistoryList == null || maintainHistoryList.isEmpty()))
        {
            // 更新设备状态
            Map<String, Object> params = Maps.newHashMap();
            params.put("id", maintainEntityDb.getEquipmentId());
            params.put("status", equipmentStatus);
            equipmentDao.updateStatus(params);
        }

        // 产生的维修费用从国鑫公司支出，并添加到支出交易
        handleMaintainCost(equipmentMaintainEntity);
    }

    @Override
    public void delete(Long maintainId) {
        equipmentMaintainDao.delete(maintainId);
    }

    @Override
    public void deleteBatch(Long[] maintainIds) {
        equipmentMaintainDao.deleteBatch(maintainIds);
    }


    /**
     * 产生的维修费用从国鑫公司支出，并添加到支出交易
     */
    private void handleMaintainCost(EquipmentMaintainEntity equipmentMaintainEntity)
    {
        if(equipmentMaintainEntity == null
                || equipmentMaintainEntity.getMaintainCost() == null
                || BigDecimal.ZERO.compareTo(equipmentMaintainEntity.getMaintainCost()) >= 0 )
        {
            return;
        }

        AdvOrgEntity defaultOrg = orgService.getDefaultOrg(); // 获取国鑫智能
        AdvOrgAcctEntity advOrgAcctEntity = orgAcctDao.queryByOrgId(defaultOrg.getId()); // 获取国鑫智能账号信息
        // 从国鑫的账户余额中减去这笔支出
        if(advOrgAcctEntity.getBalance() == null)
        {
            advOrgAcctEntity.setBalance(BigDecimal.ZERO);
        }
        advOrgAcctEntity.setBalance(advOrgAcctEntity.getBalance().subtract(equipmentMaintainEntity.getMaintainCost()));
        orgAcctDao.update(advOrgAcctEntity);

        // 支出交易记录
        AdvOrgAcctTxnEntity acctTxnEntity = new AdvOrgAcctTxnEntity();
        acctTxnEntity.setAcctId(advOrgAcctEntity.getId());
        acctTxnEntity.setOrgId(advOrgAcctEntity.getOrgId());
        acctTxnEntity.setAmount(equipmentMaintainEntity.getMaintainCost());
        acctTxnEntity.setCreateTime(new Date());
        acctTxnEntity.setComments("设备维修费用, 设备编码:" + (equipmentMaintainEntity.getCode() == null ? "" : equipmentMaintainEntity.getCode()));
        orgAcctTxnDao.save(acctTxnEntity);
    }
}
